# coding: utf-8

from datetime import date

from sqlalchemy.orm import validates

from exts import db


class FundWorth(db.Model):
    """
    基金净值
    """
    __tablename__ = "fund_worth"
    __table_args__ = (
        db.UniqueConstraint("fund", "worth_date", name="idx_fund_worth"),
    )
    id = db.Column(db.Integer, primary_key=True, autoincrement=True, nullable=False, comment="ID")
    fund = db.Column(db.CHAR(6), nullable=False, comment="基金代码")
    worth_date = db.Column(db.Date, nullable=False, comment="净值日期")
    unit_worth = db.Column(db.DECIMAL(8, 4), nullable=False, comment="单位净值")
    cumulative_worth = db.Column(db.DECIMAL(8, 4), nullable=False, comment="累计净值")


class FundBasic(db.Model):
    """
    关注基金的基本信息
    """
    __tablename__ = "fund_basic"
    id = db.Column(db.Integer, primary_key=True, autoincrement=True, nullable=False, comment="ID")
    fund = db.Column(db.CHAR(6), nullable=False, unique=True, index=True, comment="基金代码")
    name = db.Column(db.String(50), nullable=False, comment="基金名称")
    est_date = db.Column(db.Date, nullable=False, default="1970-01-01", comment="成立日期")
    ttype = db.Column(db.CHAR(2), nullable=False, comment="类型：股基;债基;货基")
    company = db.Column(db.String(12), nullable=False, comment="基金公司")
    bank = db.Column(db.String(12), nullable=False, comment="托管银行")
    index = db.Column(db.CHAR(6), comment="指数")
    worth_date = db.Column(db.Date, nullable=False, default="1970-01-01", comment="净值日期")
    unit_worth = db.Column(db.DECIMAL(8, 4), nullable=False, default=0, comment="单位净值")

    set_ttype = {"货基", "股基", "债基"}

    @property
    def dict_(self):
        _dict = self.__dict__
        for key in _dict.keys():
            if isinstance(_dict[key], date):
                _dict[key] = str(_dict[key])
        if _dict.get("_sa_instance_state"):
            _dict.pop("_sa_instance_state")
        return _dict

    @validates("ttype")
    def validate_ttype(self, key, ttype):
        if ttype not in self.set_ttype:
            raise Exception("基金类型只能是货基、债基、股基中的一个")
        return ttype


class FundHold(db.Model):
    """
    持有的基金
    """
    __tablename__ = "fund_hold"
    __table_args__ = (
        db.UniqueConstraint("acc_id", "fund", name="idx_fund_hold"),
    )
    id = db.Column(db.Integer, primary_key=True, autoincrement=True, nullable=False, comment="ID")
    acc_id = db.Column(db.CHAR(6), nullable=False, comment="账户ID")
    fund = db.Column(db.CHAR(6), nullable=False, comment="基金代码")
    name = db.Column(db.String(30), nullable=False, comment="基金名称")
    begin_date = db.Column(db.Date, nullable=False, comment="开始投资日期")
    hold_cost = db.Column(db.DECIMAL(13, 2), nullable=False, comment="持有成本")
    hold_num = db.Column(db.DECIMAL(13, 2), nullable=False, comment="持有数量")


class FundTrade(db.Model):
    """
    基金交易记录
    """
    __tablename__ = "fund_trade"
    __table_args__ = (
        db.UniqueConstraint("acc_id", "fund", "post_date", name="idx_fund_trade"),
    )
    id = db.Column(db.Integer, primary_key=True, autoincrement=True, nullable=False, comment="ID")
    trade_id = db.Column(db.CHAR(10), nullable=False, comment="交易ID")
    acc_id = db.Column(db.CHAR(6), nullable=False, comment="账户ID")
    fund = db.Column(db.CHAR(6), nullable=False, comment="基金代码")
    post_date = db.Column(db.Date, nullable=False, comment="过帐日期")
    operation = db.Column(db.CHAR(10), nullable=False, comment="操作类型")
    amount = db.Column(db.DECIMAL(10, 2), nullable=False, default=0, comment="金额")
    number = db.Column(db.DECIMAL(10, 2), nullable=False, default=0, comment="份额")
    profit = db.Column(db.DECIMAL(10, 2), nullable=False, default=0, comment="盈利")
